feat: add Google Antigravity support#992
Conversation
📝 WalkthroughWalkthroughThis pull request adds support for Google Antigravity as a selectable editor in Nuxt DevTools. The implementation adds a new RPC method Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
packages/devtools/client/setup/client-rpc.ts (1)
43-45: ⚡ Quick winAdd
noopener,noreferrertowindow.open().Links opened via the
window.openJavaScript function are also vulnerable to reverse tabnapping. Unlike HTML<a target="_blank">anchor elements,<a>,<area>, and<form>elements withtarget="_blank"implicitly provide the same rel behavior asrel="noopener"— butwindow.open()does not receive this implicit protection. Ifwindow.openeris set, a page can trigger a navigation in the opener regardless of security origin; to prevent this, userel=noopener.🛡️ Proposed fix
- async openUrl(url: string) { - window.open(url, '_blank') - }, + async openUrl(url: string) { + window.open(url, '_blank', 'noopener,noreferrer') + },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/devtools/client/setup/client-rpc.ts` around lines 43 - 45, The openUrl method currently calls window.open(url, '_blank') which is vulnerable to reverse tabnabbing; update the openUrl function to pass the appropriate features string (e.g., 'noopener,noreferrer') or explicitly set the new window's opener to null so that window.opener cannot be used: modify async openUrl(url: string) in client-rpc.ts to call window.open(url, '_blank', 'noopener,noreferrer') (or set const win = window.open(...); if (win) win.opener = null;) to ensure noopener behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/devtools/client/setup/client-rpc.ts`:
- Around line 43-45: The openUrl client RPC (function openUrl) currently calls
window.open(url, '_blank') with no validation, allowing arbitrary-URL injection
when broadcast; fix by validating and sanitizing the incoming URL before
opening: parse the url string (new URL(url) in a try/catch), ensure the protocol
is either "https:" (and optionally "http:" if acceptable), and optionally check
against a small whitelist of allowed hostnames or same-origin rules; if
validation fails, do not call window.open and instead call console.warn or log
the rejected URL; update the openUrl handler to perform this validation and only
call window.open for validated URLs.
In `@packages/devtools/src/server-rpc/general.ts`:
- Around line 222-225: The URL built in the antigravity branch uses raw path and
suffix which breaks for spaces, backslashes and special characters; update the
branch where editor === 'antigravity' to URL-encode both path and suffix before
calling ctx.rpc.broadcast.openUrl (e.g., normalize Windows backslashes to
forward slashes on path, then apply encodeURIComponent to the path and to
suffix) and use those encoded values when constructing the query string so
openUrl receives a safe, valid URL.
---
Nitpick comments:
In `@packages/devtools/client/setup/client-rpc.ts`:
- Around line 43-45: The openUrl method currently calls window.open(url,
'_blank') which is vulnerable to reverse tabnabbing; update the openUrl function
to pass the appropriate features string (e.g., 'noopener,noreferrer') or
explicitly set the new window's opener to null so that window.opener cannot be
used: modify async openUrl(url: string) in client-rpc.ts to call
window.open(url, '_blank', 'noopener,noreferrer') (or set const win =
window.open(...); if (win) win.opener = null;) to ensure noopener behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 2fc096cf-cf0f-4b8d-9910-068684c6b6bb
📒 Files selected for processing (4)
packages/devtools-kit/src/_types/rpc.tspackages/devtools/client/pages/settings.vuepackages/devtools/client/setup/client-rpc.tspackages/devtools/src/server-rpc/general.ts
| async openUrl(url: string) { | ||
| window.open(url, '_blank') | ||
| }, |
There was a problem hiding this comment.
openUrl broadcasts to all clients with no URL validation — arbitrary-URL injection risk.
openUrl is now a general-purpose client RPC callable by any server-side code holding ctx.rpc. A malicious or compromised Nuxt module can call ctx.rpc.broadcast.openUrl('https://attacker.example/phish'), causing every connected DevTools client to open the attacker URL silently in a new tab. There is no restriction at the client handler to antigravity.google or even to the https: scheme (a javascript: URL, while blocked by most browsers in window.open, is a valid string today).
At minimum, validate the protocol before calling window.open:
🛡️ Proposed fix
async openUrl(url: string) {
- window.open(url, '_blank')
+ if (!url.startsWith('https://'))
+ return
+ window.open(url, '_blank', 'noopener,noreferrer')
},📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| async openUrl(url: string) { | |
| window.open(url, '_blank') | |
| }, | |
| async openUrl(url: string) { | |
| if (!url.startsWith('https://')) | |
| return | |
| window.open(url, '_blank', 'noopener,noreferrer') | |
| }, |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/devtools/client/setup/client-rpc.ts` around lines 43 - 45, The
openUrl client RPC (function openUrl) currently calls window.open(url, '_blank')
with no validation, allowing arbitrary-URL injection when broadcast; fix by
validating and sanitizing the incoming URL before opening: parse the url string
(new URL(url) in a try/catch), ensure the protocol is either "https:" (and
optionally "http:" if acceptable), and optionally check against a small
whitelist of allowed hostnames or same-origin rules; if validation fails, do not
call window.open and instead call console.warn or log the rejected URL; update
the openUrl handler to perform this validation and only call window.open for
validated URLs.
| if (editor === 'antigravity') { | ||
| ctx.rpc.broadcast.openUrl(`https://antigravity.google/open?file=${path}${suffix}`) | ||
| return true | ||
| } |
There was a problem hiding this comment.
File path is not URL-encoded — paths with spaces or special characters will generate broken URLs.
path is an absolute OS path (e.g., /home/john/my projects/src/App.vue) and suffix contains colons (e.g., :10:5). Neither is encoded before being spliced into the query string, so:
- A space in any directory name produces an invalid URL (space is not a legal query-string character).
- Characters like
#,&, and?in a path fragment or break the query string. - Windows paths with backslashes pass through unescaped.
🐛 Proposed fix
- ctx.rpc.broadcast.openUrl(`https://antigravity.google/open?file=${path}${suffix}`)
+ ctx.rpc.broadcast.openUrl(`https://antigravity.google/open?file=${encodeURIComponent(path + suffix)}`)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (editor === 'antigravity') { | |
| ctx.rpc.broadcast.openUrl(`https://antigravity.google/open?file=${path}${suffix}`) | |
| return true | |
| } | |
| if (editor === 'antigravity') { | |
| ctx.rpc.broadcast.openUrl(`https://antigravity.google/open?file=${encodeURIComponent(path + suffix)}`) | |
| return true | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/devtools/src/server-rpc/general.ts` around lines 222 - 225, The URL
built in the antigravity branch uses raw path and suffix which breaks for
spaces, backslashes and special characters; update the branch where editor ===
'antigravity' to URL-encode both path and suffix before calling
ctx.rpc.broadcast.openUrl (e.g., normalize Windows backslashes to forward
slashes on path, then apply encodeURIComponent to the path and to suffix) and
use those encoded values when constructing the query string so openUrl receives
a safe, valid URL.
Resolves #987
Description
This PR adds support for Google Antigravity as a selectable code editor in Nuxt DevTools.
Since Antigravity is a browser-based IDE, it cannot use standard CLI spawn commands (which results in an
ENOENTerror when usinglaunch-editor). To solve this, this implementation intercepts theopenInEditorrequest on the server ifantigravityis selected, and instead broadcasts anopenUrlevent to the client to handle the navigation via the browser.Changes
antigravityto the editor options insettings.vue.openUrltoClientFunctionsRPC types.openUrlinclient-rpc.tsusingwindow.open.setupGeneralRPCslightly to accessctx.rpc.broadcastand handle the Antigravity URL scheme bypassinglaunch-editor.